﻿using Admin.NET.Core.Fitter;

namespace Admin.NET.Application.Service;

/// <summary>
/// 血液预约
/// </summary>
public class InvYueXueService : BaseServiceBill<InvYueXue>
{
    private readonly SqlSugarRepository<InvYueXueMingXi> _repMingXi; //入库明细
    private readonly SqlSugarRepository<BasXueYePinZhong> _basXueYePinZhong;
    private readonly SqlSugarRepository<SysOrg> _sysOrg;

    public InvYueXueService(IServiceScopeFactory scopeFactory, SqlSugarRepository<InvYueXueMingXi> repMingXi
        , SqlSugarRepository<BasXueYePinZhong> basXueYePinZhong, SqlSugarRepository<SysOrg> sysOrg) : base(scopeFactory)
    {
        _repMingXi = repMingXi;
        _basXueYePinZhong = basXueYePinZhong;
        _sysOrg = sysOrg;
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    [AllowAnonymous]
    public async Task<SqlSugarPagedList<InvYueXueOutput>> Page(InvYueXuePageInput input)
    {
        var invKuCunList = await Queryable.FuzzyQuery(input.Keyword, new List<string> { "Id" })
           .WhereIF(input.StartTime.HasValue, t => t.CreateTime >= input.StartTime)
           .WhereIF(input.EndTime.HasValue, t => t.CreateTime <= input.EndTime)
           .WhereIF(input.danJuZhuangTai.HasValue(), t => t.danJuZhuangTai == input.danJuZhuangTai)
           .Select<InvYueXueOutput>()
           .OrderByDescending(it => it.Id)
           .ToPagedListAsync(input.Page, input.PageSize);

        return invKuCunList;
    }

    /// <summary>
    /// 通过Id获取
    /// </summary>
    [AllowAnonymous]
    public InvYueXueZhuCongOutput Get(string id)
    {
        var zhuBiao = GetById<InvYueXueOutput>(id);
        var mingXiList = _repMingXi.Queryable.Where(t => t.invYueXueId == id).ToList().Adapt<List<InvYueXueMingXiOutput>>();
        // 获取产品名字
        var pinZhongIdList = mingXiList.Select(t => Convert.ToInt64(t.xueYePinZhong)).ToList();
        var pinZhongList = _basXueYePinZhong.AsQueryable().Where(t => pinZhongIdList.Contains(t.Id)).ToList();
        foreach (var item in mingXiList)
        {
            item.xueYePinZhongMingChen = pinZhongList.Where(t => t.Id == Convert.ToInt64(item.xueYePinZhong)).Select(t => t.mingCheng).FirstOrDefault();
        }
        return new InvYueXueZhuCongOutput
        {
            zhuBiao = zhuBiao,
            mingXiList = mingXiList
        };
    }

    /// <summary>
    /// 新增成功后返回主表
    /// </summary>
    [OccurSimultaneously(5, "dingXueYiYuanId")]
    public InvYueXue Add(InvYueXueAddInput input)
    {
        input.danJuZhuangTai = DanJuZhuangTai.待审核; // 一般情况单击新增后默认已生效

        // 插入主表
        var zhuBiao = AddWithInput(input);

        // 明细表添加主表id
        foreach (var item in input.mingXiList)
        {
            item.invYueXueId = zhuBiao.Id; // 主表Id
        }
        _repMingXi.InsertRange(input.mingXiList);

        return zhuBiao;
    }

    /// <summary>
    /// 审核
    /// </summary>
    [AllowAnonymous]
    public bool AuditBill(InvYueXueAuditInput input)
    {
        return Audit(input);
    }

    /// <summary>
    /// 作废单据
    /// </summary>
    public bool Cancel(BaseBillCancelInput input)
    {
        return CancelBill(input);
    }

    /// <summary>
    /// 检索是否存在待审核的单据
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<bool> CheckIsDaiShenHeBill()
    {
        return await _rep.AsQueryable().Where(t => t.danJuZhuangTai == DanJuZhuangTai.待审核).CountAsync() > 0;
    }

    /// <summary>
    /// 单据退审功能
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [AllowAnonymous]
    public bool RejectAuditBill(InvYueXueAuditInput input)
    {
        var eff = _rep.AsUpdateable(new InvYueXue() { Id = input.Id, danJuZhuangTai = DanJuZhuangTai.待审核, UpdateTime = DateTime.Now, UpdateUserName = input.auditUserName })
             .UpdateColumns(it => new { it.remark, it.UpdateTime, it.UpdateUserId, it.UpdateUserName, it.danJuZhuangTai }).ExecuteCommand();

        if (eff > 0)
        {
            AddOptBill(input.Id, "退审", input);
        }
        return eff > 0;
    }

    /// <summary>
    /// 获取指定协议医院的订血列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<SqlSugarPagedList<InvYueXueOutput>> CheckYiYuanDingXueList(CheckYiYuanDingXueListInput input)
    {
        var dingXueYiYuanId = await _sysOrg.AsQueryable().Where(t => t.Code == input.dingXueYiYuanCode).Select(t => t.Id).FirstAsync();

        var dingXueList = await _rep.AsQueryable().FuzzyQuery(input.Keyword, new List<string> { "Id", "faXueLeiXing" }).Where(t => t.dingXueYiYuanId == dingXueYiYuanId)
           .Select<InvYueXueOutput>()
           .OrderByDescending(it => it.CreateTime)
           .ToPagedListAsync(input.Page, input.PageSize);

        return dingXueList;
    }

    /// <summary>
    /// 根据勾选的单据入参获取品种汇总信息
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<List<CheckDingXuePingZhongHuiZong>> CheckDingXuePingZhongHuiZong(CheckDingXuePingZhongHuiZongInput input)
    {
        var dingXueMingXiList = await _repMingXi.AsQueryable().Where(t => input.idList.Contains(t.invYueXueId))
                                .InnerJoin<BasXueYePinZhong>((mingXi, pinZhong) => mingXi.xueYePinZhong == pinZhong.Id.ToString())
                                .GroupBy((mingXi, pinZhong) => new { mingXi.xueYePinZhong, pinZhong.mingCheng, mingXi.danWei })
                                .Select((mingXi, pinZhong) => new CheckDingXuePingZhongHuiZong
                                {
                                    xueYePinZhongId = mingXi.xueYePinZhong,
                                    xueYePinZhongName = pinZhong.mingCheng,
                                    rhYangRongLiangA = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "+", mingXi.rongLiangA, 0)),
                                    rhYangRongLiangB = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "+", mingXi.rongLiangB, 0)),
                                    rhYangRongLiangO = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "+", mingXi.rongLiangO, 0)),
                                    rhYangRongLiangAB = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "+", mingXi.rongLiangAB, 0)),
                                    rhYinRongLiangA = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "-", mingXi.rongLiangA, 0)),
                                    rhYinRongLiangB = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "-", mingXi.rongLiangB, 0)),
                                    rhYinRongLiangO = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "-", mingXi.rongLiangO, 0)),
                                    rhYinRongLiangAB = SqlFunc.AggregateSum(SqlFunc.IIF(mingXi.rhD == "-", mingXi.rongLiangAB, 0)),
                                    danWei = mingXi.danWei,
                                }).ToListAsync();

        return dingXueMingXiList;
    }

    /// <summary>
    /// 批量标记发血
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [AllowAnonymous]
    public bool BatchMarkFaXue(BatchMarkFaXueInput input)
    {
        var invYueXuelist = new List<InvYueXue>();
        foreach (var item in input.idList)
        {
            invYueXuelist.Add(new InvYueXue
            {
                Id = item,
                // 需求要求标记为已发血，审核后已经是已生效状态了，勾选订单后发血才是已发血状态
                danJuZhuangTai = "已发血",
                faXueDanHao = input.faXueDanHao
            });
        }
        var eff = _rep.AsUpdateable(invYueXuelist)
                     .UpdateColumns(it => new { it.UpdateTime, it.UpdateUserId, it.UpdateUserName, it.danJuZhuangTai, it.faXueDanHao }).ExecuteCommand();

        if (eff > 0)
        {
            foreach (var item in input.idList)
            {
                AddOptBill(item, "协议医院出库", input);
            }
        }
        return eff > 0;
    }
}

